Chapter 3 Procedures
#CSAPP
使用汇编语言支持 Procedures 需要实现以下机制
- 传递控制
- 传递数据
- 分配和释放内存
这三个机制的实现都离不开栈空间的合理利用
传递控制
call 指令将下一条指令的地址(返回地址)压入栈中,并跳跃到 Label 指定的内存段开始执行
ret 将栈顶的返回地址弹出并跳跃到返回地址(需要保证 %rsp 正确地处在返回地址处)
传递数据
对于简单的基础类型数据的传入而言
- 当传入参数小于 6 个时,可以按如图顺序储存在指定的寄存器中
- 当传入参数超过 6 个时,第 n 到第 7 个参数依次被压入栈中(需要满足对齐要求),恰好位于返回地址之上,归属调用者的栈帧
对于基础数据类型的数据的返回,储存在 %rax 中
局部内存分配
局部内存包括栈和寄存器。各个 procedures 的栈帧是互不重叠的,直接增减 %rsp 进行分配和释放即可,而寄存器是公用的,需要一些额外的规则来保证 caller 储存的数据不会再 callee 中被毁坏。
必须储存在栈空间上的情况
- 寄存器不够用
- & 取地址运算符被使用
- 是(复杂的)结构体或者数组
注意栈空间上的所有数据储存必须满足对应数据长度的对齐要求
- %rbx, %rbp, %r12-%r15 为 callee-saved registers。当 Q 被 P 调用时,如果要使用这些寄存器,需要将他们压入栈中,返回 P 之前按对应的顺序弹出,保证返回至 P 时这些寄存器的值不会发生改变
- %rsp
- 剩余所有寄存器都被称为 caller-saved registers。被调用者没有义务保持他们在调用后的不变性,调用者在有需要时需要自行压入栈中保存